package net.sf.borg.ui.systemLogin;

import java.awt.BorderLayout;
import java.awt.Choice;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;

import java.util.List;

/**
 * Class NameLoginView
 * 
 * NameLoginView provides a GUI interface to logging into a system using
 * a single validation ID.  When choosing an existing ID, the user will
 * see a list of pre-existing IDs, so do not use this GUI if privacy
 * is a requirement.
 * 
 * BORG/Open Source Information here.
 *
 * Created in UF Software Engineering - Summer 2009
 * @author Matthew Carroll
 */

public class NameLoginView extends JDialog {
	
	/*
	 *Private interface implemented by each LoginState
	 *This interface insures that we can grab the given
	 *username from whatever GUI is currently displayed
	 */
	private interface LoginPanel {
		String getUsername();
	}
	
	/*
	 * Login GUI that allows the user to enter a new
	 * username in order to create a new "account".  Also
	 * provides a button that should allow the user to choose
	 * an existing username, but this button is disabled when
	 * there are no existing users.
	 */
	private class CreateUserPanel extends JPanel implements LoginPanel
	{
		private String username;
		private TextField userField;
		
		public CreateUserPanel() {
			//build GUI
			this.setLayout(new BorderLayout());
			JPanel labelPane = new JPanel();
			labelPane.add( new Label("Enter New Username"));
			add(labelPane, BorderLayout.NORTH);
			
			JPanel textPane = new JPanel();
			userField = new TextField(25);
			textPane.add(userField);
			add(textPane, BorderLayout.CENTER);
			
			JPanel buttonPane = new JPanel();
			JButton newUserB = new JButton("Create User");
			JButton chooseUserB = new JButton("Choose Existing User");
			JButton cancelB = new JButton("Exit");
			buttonPane.add(newUserB);
			if((existingUsers != null) && (existingUsers.size() > 0))
				buttonPane.add(chooseUserB);
			buttonPane.add(cancelB);
			add(buttonPane, BorderLayout.SOUTH);
			setDefaultCloseOperation(DISPOSE_ON_CLOSE);
			pack();
			
			//Set action for "create user" button
			newUserB.addActionListener(
					new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							setUsername();
							acceptInput();
						}
					} 
			);
			
			//Set action for switching to the create user view
			chooseUserB.addActionListener(
					new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							openState(LoginState.CHOOSE_USER_STATE);
						}
					} 
			);
			
			//Set action for the "cancel" button
			cancelB.addActionListener(
					new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							doClose();
						}
					} 
			);
		}
		
		//Implementing LoginPanel interface
		public String getUsername() {
			return this.username;
		}
		
		private void setUsername() {
			this.username = userField.getText();
		}
		
		private void acceptInput() {
			dispose();
		}
		
		private void doClose() {
			username = null;
			dispose();
		}
	}
	
	/*
	 * SelectUserPanel provides a GUI representation which allows a
	 * user to select a user ID from a pre-existing list of user IDs.
	 * If there are no existing user IDs then the user SHOULD NOT be
	 * able to reach this view.
	 */
	private class SelectUserPanel extends JPanel implements LoginPanel
	{
		private String username;
		private Choice userChoice;
		
		public SelectUserPanel() {
			//build GUI
			this.setLayout(new BorderLayout());
			this.setSize(250, 200);
			add(new Label("Choose User:"), BorderLayout.NORTH);
			userChoice = new Choice();
			for( String name : existingUsers ) {
				userChoice.add(name);
			}
			userChoice.setSize(300, 30);
			add(userChoice, BorderLayout.CENTER);
			
			JPanel buttonPane = new JPanel();
			JButton newUserB = new JButton("Select");
			JButton chooseUserB = new JButton("Create New User");
			JButton cancelB = new JButton("Exit");
			buttonPane.add(newUserB);
			buttonPane.add(chooseUserB);
			buttonPane.add(cancelB);
			add(buttonPane, BorderLayout.SOUTH);
			setDefaultCloseOperation(DISPOSE_ON_CLOSE);
			pack();
			
			//Set action for when user tries to choose a user ID
			newUserB.addActionListener(
					new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							setUsername();
							acceptInput();
						}
					} 
			);
			
			//Set action for when user wants to go create a new user ID
			chooseUserB.addActionListener(
					new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							openState(LoginState.CREATE_USER_STATE);
						}
					} 
			);
			//Set action for when user cancels the login
			cancelB.addActionListener(
					new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							doClose();
						}
					} 
			);
		}
		
		public String getUsername() {
			return this.username;
		}
		
		private void setUsername() {
			this.username = userChoice.getSelectedItem();
		}
		
		private void acceptInput() {
			dispose();
		}
		
		private void doClose() {
			username = null;
			dispose();
		}
	}
	
	private LoginState currState;			/* What particular GUI representation do we want */
	private CreateUserPanel createPanel;	/* swing panel for creating a new user */
	private SelectUserPanel selectPanel;	/* swing panel for selecting a user from list*/
	private LoginPanel currPanel;			/* NOT a swing panel, but an interface for grabbing usernames */
	private List<String> existingUsers;		/* list of existing users in system */

	//public definitions of GUI states
	public enum LoginState { CREATE_USER_STATE, CHOOSE_USER_STATE }
	
	public NameLoginView(LoginState startState, List<String> existingUsers) {
		this.setTitle("Login");
		this.setModal(true);
		this.setSize(250, 200);
		this.existingUsers = existingUsers;
		currState = startState;
		setup();
	}
	
	//Opens a particular login view for this system
	private void openState(LoginState state) {
		currState = state;
		setup();
	}
	
	public LoginState getState() {
		return currState;
	}
	
	private void setup() {
		//get and clear content pane
		Container holder = this.getContentPane();
		holder.removeAll();
		
		if(currState == LoginState.CREATE_USER_STATE)	//show create user view
		{
			createPanel = new CreateUserPanel();
			holder.add(createPanel);
			pack();
			currPanel = createPanel;
		}
		else if(currState == LoginState.CHOOSE_USER_STATE)	//show choose user view
		{
			selectPanel = new SelectUserPanel();
			holder.add(selectPanel);
			pack();
			currPanel = selectPanel;
		}
		
		//center view on screen
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		this.setLocation( (dim.width - this.getWidth())/2, (dim.height - this.getHeight())/2 );
	}
	
	private String getUser() {
		return currPanel.getUsername();
	}
	
	public String runLoginView() 
	{
		setup();
		this.setVisible(true);
		return getUser();
	}
	
}
